import Blockutils from "@/utils/BlockUtils";
import { MotaInterface } from "@/mota";
import ScrollTool from "@/mota/tools/ScrollTool";
import { PropsInterface } from "@/mota/data/ItemDataUnit";
import PackUtils from "@/mota/utils/HeroUtils/PackUtils";
import { AttackResult } from "@/mota/utils/HeroUtils/AttributeUtils";
import { AttckTypeInfo, BattleInfo, battleList, GetAttckTypeInfo } from "@/mota/data/BattleDataUtils";

export type EnemyMapInfo = [BattleInfo, AttckTypeInfo, AttackResult];

export default class EnemyMapUtils extends ScrollTool<EnemyMapInfo> implements MotaInterface, PropsInterface {

	public pack!: PackUtils;

	public itemType!: PropsInterface["itemType"];

	public block: Blockutils = new Blockutils();

	public ZIndex: number = 4;

	public constructor() {
		super({
			Left: 4,
			Top: 0,
			Width: 11,
			Height: 11,
			Padding: 0.25,
			ItemWidth: 11 - 0.5 - 0.1,
			ItemHeight: 1 + 0.25,
			ItemPadding: 0.1,
			ScrollWidth: 0.1,
		});
	}

	public get isOpen() {
		return this.block.IsBlockUp;
	}

	public SetPack: PropsInterface["SetPack"] = async (pack, itemType) => {
		this.pack = pack;
		this.itemType = itemType;
	}

	public Use: PropsInterface["Use"] = async () => {
		const { pack: { hero, hero: { Mota: { tip, map: { map: { unit } } } } } } = this;

		const imageSet = new Set(Array.from(unit)
			.filter(([, show, , , event]) => show && event !== undefined && event.has("battle"))
			.map(unit => unit[0]));

		const showList = battleList.filter(info => imageSet.has(info[0]));
		if (showList.length === 0) {
			tip.AddMessage("本层无怪物");
			return false;
		}

		this.List.Value = showList.map(enemy => {
			return [enemy, GetAttckTypeInfo(enemy[6]), hero.Attribute.AttackCalc(enemy[0])];
		});

		await this.block.Wait(undefined, () => {
			this.SelectIndex = undefined;
		});
		return true;
	}

	public InView(): boolean {
		const { isOpen } = this;
		return isOpen;
	}

	public JudgeKey: MotaInterface["JudgeKey"] = (keyUtils): void => {
		if (!this.InView()) { return; }

		for (const key of keyUtils.keyHistory) {
			if (key === "Escape" || key === "e") {
				this.block.Release();
				keyUtils.delete(key);
			}
			else if (key === "ArrowUp") {
				this.SelectLast(true);
				keyUtils.delete(key);
			}
			else if (key === "ArrowDown") {
				this.SelectNext(true);
				keyUtils.delete(key);
			}
		}
	}

	public mousewheel: MotaInterface["mousewheel"] = (delta: number) => {
		if (!this.InView()) { return; }
		const isDown = delta > 0;
		this.Progress += isDown ? 1 : -1;
	}

	public Draw: MotaInterface["Draw"] = (draw) => {
		if (!this.InView()) { return; }

		const { pack: { hero: { Mota: { tip } } } } = this
		if (this.Length.Value === 0) {
			tip.AddMessage("本层无怪物");
			this.block.Release();
			return;
		}

		const { _2d } = draw;
		_2d.save();

		_2d.fillStyle = "#000000AA";
		draw.fillRect(4, 0, 11, 11);

		const lineHeight = 1 / 3;
		_2d.fillStyle = "#FFFFFF";
		_2d.strokeStyle = "#000000";
		draw.SetFont(400, lineHeight, "Mota");
		_2d.textAlign = "left";
		_2d.textBaseline = "top";
		draw.SetLineWidth(1 / 16);

		const padding = 0.25;
		const hpadding = padding / 2;

		let selectSize: readonly [number, number, number, number] | undefined = undefined;

		for (const [[battle, attckType, res], isSelect, [x, y, , h], borderSize] of this.GetItemsSize()) {
			const [image, hp, attack, defence, gold, exp] = <BattleInfo>battle;
			draw.DrawUnti([image, true, [x, y], "run"]);
			draw.fillText(`${image}`, x + h, y + 0.24);

			draw.DrawImage("血量", true, 0, [x + h, y + 0.24 + 0.5, lineHeight, lineHeight]);
			draw.fillText(`${hp}`, x + h + 0.4, y + 0.24 + 0.5);

			draw.DrawImage("神圣盾", true, 0, [x + h + 2.7 - 0.5, y + 0.24 + 0, lineHeight, lineHeight]);
			draw.fillText(`${defence}`, x + h + 3.1 - 0.5, y + 0.24 + 0);
			draw.DrawImage("神圣剑", true, 0, [x + h + 2.7 - 0.5, y + 0.24 + 0.5, lineHeight, lineHeight]);
			draw.fillText(`${attack}`, x + h + 3.1 - 0.5, y + 0.24 + 0.5);

			draw.DrawImage("幸运金币", true, 0, [x + h + 2.7 + 2.1, y + 0.24 + 0, lineHeight, lineHeight]);
			draw.fillText(`${gold}`, x + h + 3.1 + 2.1, y + 0.24 + 0);
			draw.fillText(`特攻：${attckType[1]}`, x + h + 2.7 + 2.1, y + 0.24 + 0.5);

			draw.DrawImage("经验卷轴", true, 0, [x + h + 2.7 + 4.4, y + 0.24 + 0, lineHeight, lineHeight]);
			draw.fillText(`${exp}`, x + h + 3.1 + 4.4, y + 0.24 + 0);
			const attrckResult = res === undefined ? "无战斗信息" : res === "unable" ? "无法战胜" : res === "fail" ? "挑战失败" : res === 0 ? "无损伤" : res;
			draw.fillText(`${attrckResult}`, x + h + hpadding + 2.7 + 4.4, y + 0.24 + 0.5);

			_2d.strokeStyle = "#AAAAAA";
			if (isSelect) { selectSize = borderSize; }
			draw.strokeRect(...borderSize);
		}

		if (selectSize) {
			_2d.strokeStyle = "#00FF00";
			draw.strokeRect(...selectSize);
		}

		{
			const scrollSize = this.GetScrollSize();
			if (scrollSize) {
				const [[x, y, w, h], [sx, sy, sw, sh]] = scrollSize;
				_2d.fillStyle = "#00000044";
				draw.fillRect(x - 0.125, y - 0.25, w, h);
				_2d.fillStyle = "#666";
				draw.fillRect(sx - 0.125, sy - 0.25, sw, sh);
			}
		}

		_2d.restore();
	}
}
